package model.subject;

import java.util.ArrayList;
import java.util.Collection;

import commands.Command;

import model.value.VersionnedValue;
import model.value.VersionnedValueImpl;

import model.algorithmes.SpreadingAlgorithme;

import model.observer.SensorObserver;

/**
 * Implémentation de l'interface Sensor.
 */
public class SensorImpl implements Sensor, Lockable {
	
	private VersionnedValue value;
	
	private Collection<SensorObserver> observers;
	private SpreadingAlgorithme spreadingAlgorithme;
	
	private Command notifyChangesToApplicationPanelCommand;
	private Command allowChangesOnApplicationPanelCommand;
	private Command blockChangesOnApplicationPanelCommand;
	
	public SensorImpl() {
		value = new VersionnedValueImpl();
		observers = new ArrayList<SensorObserver>();
	}
	
	@Override
	public void attach(SensorObserver observer) {
		observers.add(observer);
	}

	@Override
	public void detach(SensorObserver observer) {
		observers.remove(observer);
	}

	@Override
	public Collection<SensorObserver> getObservers() {
		return observers;
	}
	
	@Override
	public void setValue(int value) {
		if(this.value.getVersion() != value) {
			spreadingAlgorithme.setValue(value);
			tick();
		}
	}
	
	@Override
	public VersionnedValue getValue() {
		return spreadingAlgorithme.getValue();
	}
	
	@Override
	public VersionnedValue getRealValue(){
		return value;
	}

	private void tick() {
		// Execution de la diffusion
		spreadingAlgorithme.execute();
	}

	@Override
	public void setSpreadingAlgorithme(SpreadingAlgorithme spreadingAlgorithme) {
		this.spreadingAlgorithme = spreadingAlgorithme;
		spreadingAlgorithme.configure(this);
	}

	@Override
	public void setRealValue(int value) {
		this.value.setValue(value);
		notifyChangesToApplicationPanelCommand.execute();
	}
	
	@Override
	public void allowChanges() {
		allowChangesOnApplicationPanelCommand.execute();
	}
	
	@Override
	public void blockChanges() {
		blockChangesOnApplicationPanelCommand.execute();
	}
	
	@Override
	public void setNotifyChangesToApplicationPanelCommand(Command notifyChangesToApplicationPanelCommand) {
		this.notifyChangesToApplicationPanelCommand = notifyChangesToApplicationPanelCommand;
	}
	
	@Override
	public void setAllowChangesOnApplicationPanelCommand(Command allowChangesOnApplicationPanelCommand) {
		this.allowChangesOnApplicationPanelCommand = allowChangesOnApplicationPanelCommand;
	}
	
	@Override
	public void setBlockChangesOnApplicationPanelCommand(Command blockChangesOnApplicationPanelCommand) {
		this.blockChangesOnApplicationPanelCommand = blockChangesOnApplicationPanelCommand;
	}
		
}
